package com.wangyf.jvm.c_002_customer_clzlodr;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

/**
 * 简单的加密一个class文件
 * 首先清楚一个二进制字符串 和另外一个数字进行异或，得出的结果再和此数字进行第二次异或，得到的值为原值
 * 1.将class文件进行异或计算加密
 * 2.使用自定义类加载器加载类的时候进行异或解密
 */
public class T02_ClassLoaderWithEncription extends ClassLoader{
    public static int seed = 0B10110110;

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        File f = new File("D:/msb-learning-code/", name.replace('.', '/').concat(".wyfclass"));
        try {
            FileInputStream fis = new FileInputStream(f);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            int b = 0;

            while ((b=fis.read()) !=0) {
                baos.write(b ^ seed);
            }

            byte[] bytes = baos.toByteArray();
            baos.close();
            fis.close();//可以写的更加严谨

            return defineClass(name, bytes, 0, bytes.length);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return super.findClass(name); //throws ClassNotFoundException
    }

    public static void main(String[] args) throws Exception {

        encFile("src.main.java.com.wangyf.jvm.c_002_customer_clzlodr.Hello");

        ClassLoader l = new T02_ClassLoaderWithEncription();
        Class clazz = l.loadClass("com.wangyf.jvm.c_002_customer_clzlodr.Hello");
        Hello h = (Hello)clazz.newInstance();
        h.m();

        System.out.println(l.getClass().getClassLoader());
        System.out.println(l.getParent());
    }

    private static void encFile(String name) throws Exception {
        File f = new File("D:/msb-learning-code/", name.replace('.', '/').concat(".class"));
        FileInputStream fis = new FileInputStream(f);
        FileOutputStream fos = new FileOutputStream(new File("D:/msb-learning-code/", name.replaceAll(".", "/").concat(".wyfclass")));
        int b = 0;

        while((b = fis.read()) != -1) {
            fos.write(b ^ seed);
        }

        fis.close();
        fos.close();
    }

}
